﻿using System;
using System.Configuration;
using System.Data;
using System.Data.SQLite;
using System.IO;
using log4net;
using log4net.Appender;
using log4net.Config;
using log4net.Layout;

namespace WebLog
{
    public sealed class Logger
    {
        private static readonly Lazy<Logger> instance = new Lazy<Logger>(() => new Logger());

        private Logger() { }

        public static Logger GetInstance
        {
            get
            {
                return instance.Value;
            }
        }


        public void WriteLog(Exception exception)
        {

            BasicConfigurator.Configure(GetSqliteAppender(ConfigurationManager.ConnectionStrings["log"].ConnectionString));
            LogManager.GetLogger(exception.Message).Error(exception);
        }


        private static IAppender GetSqliteAppender(string dbFilename)
        {
            var dbFile = new FileInfo(dbFilename);

            if (!dbFile.Exists)
            {
                CreateLogDb(dbFile);
            }

            var appender = new AdoNetAppender
            {
                ConnectionType = "System.Data.SQLite.SQLiteConnection, System.Data.SQLite",
                ConnectionString = String.Format("Data Source={0};Version=3;", dbFilename),
                CommandText = "INSERT INTO Log (Date, Level, Logger, Message) VALUES (@Date, @Level, @Logger, @Message)"
            };

            appender.AddParameter(new AdoNetAppenderParameter
            {
                ParameterName = "@Date",
                DbType = DbType.DateTime,
                Layout = new RawTimeStampLayout()

            });

            appender.AddParameter(new AdoNetAppenderParameter
            {
                ParameterName = "@Level",
                DbType = DbType.String,
                Layout = new Layout2RawLayoutAdapter(new PatternLayout("%level"))
            });

            appender.AddParameter(new AdoNetAppenderParameter
            {
                ParameterName = "@Logger",
                DbType = DbType.String,
                Layout = new Layout2RawLayoutAdapter(new PatternLayout("%logger"))
            });

            appender.AddParameter(new AdoNetAppenderParameter
            {
                ParameterName = "@Message",
                DbType = DbType.String,
                Layout = new Layout2RawLayoutAdapter(new PatternLayout("%message"))
            });

            appender.ActivateOptions();
            return appender;
        }

        private static void CreateLogDb(FileInfo file)
        {
            using (var conn = new SQLiteConnection())
            {
                conn.ConnectionString = string.Format("Data Source={0};New=True;Compress=True;Synchronous=Off", file.FullName);
                conn.Open();
                var cmd = conn.CreateCommand();

                cmd.CommandText =
                                 @"CREATE TABLE IF NOT EXISTS Log(
                            LogId     INTEGER PRIMARY KEY,
                            Date      DATETIME NOT NULL,
                            Level     VARCHAR(50) NOT NULL,
                            Logger    VARCHAR(255) NOT NULL,
                            Message   TEXT DEFAULT NULL
                        );";

                cmd.ExecuteNonQuery();
                cmd.Dispose();
                conn.Close();
            }
        }

    }
}

